/*
PearReview - The peer review assistant.
Copyright (C) 2009  Dimitrij Pankratz, Anton Musichin
http://www.pearreview.com, info@pearreview.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package com.pearreview.application;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.net.URLConnection;
import java.util.Locale;

import javax.swing.SwingWorker;
import javax.swing.event.EventListenerList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class VersionChecker implements Serializable {
	private static final long serialVersionUID = -3534611287342182518L;
	
	private boolean running = false;
	private EventListenerList actionListenerList = new EventListenerList();
	private Version lastVersion = null;
	private String lastHistory = null;
	private Exception lastError = null;
	
	public boolean isChecking() {
		return running;
	}
	
	public void check() {
		if(isChecking()) {
			return;
		}
		CheckSwingWorker csw = new CheckSwingWorker();
		running = true;
		csw.execute();
	}
	
	/**
	 * Adds the listener. This will be dispatched when 
	 * user click on close-tab-button
	 * @param vcl listener to add
	 */
	public void addActionListener(ActionListener vcl) {
		actionListenerList.add(ActionListener.class, vcl);
	}
	
	/**
	 * Return an array of all the listeners of the given type.
	 * @param vcl listener to remove
	 */
	public void removeActionListener(ActionListener vcl) {
		actionListenerList.remove(ActionListener.class, vcl);
	}
	
	/**
	 * Return an array of all the listeners. 
	 * @return
	 */
	protected ActionListener[] getActionListeners() {
		return actionListenerList.getListeners(ActionListener.class);
	}
	
	protected void fireActionListeners(ActionEvent event) {
		ActionListener[] listeners = getActionListeners();
		for (int i = 0; i < listeners.length ; i++ ) {
			listeners[i].actionPerformed(event);
		}
	}
	
	protected void fireActionListeners() {
		ActionEvent event = new ActionEvent(this, 
				ActionEvent.ACTION_PERFORMED, 
				null);
		fireActionListeners(event);
	}

	public Version getVersion() {
		return lastVersion;
	}
	public String getHistory() {
		return lastHistory;
	}
	public Exception getError() {
		return lastError;
	}

	private class CheckSwingWorker extends SwingWorker<String[], Void> {
		final String REQUEST_URL = "http://www.pearreview.com:80/version";
		final String REQUEST_PARAMETER =  "language=" 
				+ Locale.getDefault().getLanguage() 
				+ "&" 
				+ "version=" 
				+ PearReview.VERSION;
		
		public CheckSwingWorker() {
			
		}
		
		@Override
		protected String[] doInBackground() throws Exception {
			URL requestURL = new URL(REQUEST_URL + "?" + REQUEST_PARAMETER);
			
			URLConnection connection = requestURL.openConnection();
			
			/* post
			connection.setDoOutput(true);		
			OutputStream os = connection.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(os);
			osw.write(getRequestParameter());
			osw.flush();
			osw.close();
			*/
			
			InputStream is = connection.getInputStream();
			
			/* read in xml input */
			DocumentBuilderFactory factory = 
					DocumentBuilderFactory.newInstance();
			factory.setIgnoringComments(true);
			factory.setNamespaceAware(false);
			DocumentBuilder loader = factory.newDocumentBuilder();

			Document document = loader.parse(is);
			Element root = document.getDocumentElement();
			
			String version = null;
			String history = null;
			
			NodeList nodes = root.getChildNodes();
			
			for( int i = 0 ; i < nodes.getLength() ; i++ ) {
				Node node = nodes.item(i);
				
				if(node.getNodeName().endsWith("version")) {
					version = node.getTextContent();
				} else if(node.getNodeName().endsWith("history")) {
					history = node.getTextContent();
				}
			}
			
			return new String[]{version, history};
		}
		
		@Override
		protected void done() {
			lastError = null;
			lastVersion = null;
			lastHistory = null;
			try {
				String[] data = get();
				
				lastVersion = Version.parseVersion(data[0]);
				lastHistory = data[1];
			} catch(Exception e) {
				lastError = e;
			}
			
			running = false;
			fireActionListeners();
		}
	}
}
